package offer2

import "strings"

/**
原题链接:
https://leetcode.cn/problems/biao-shi-shu-zhi-de-zi-fu-chuan-lcof/

B站 帅地玩编程
剑指 Offer 20. 表示数值的字符串
请实现一个函数用来判断字符串是否表示数值（包括整数和小数）。

表示数值（按顺序）可以分成以下几个部分：

若干空格
一个 小数 或者 整数
（可选）一个 'e' 或 'E' ，后面跟着一个 整数
若干空格
小数（按顺序）可以分成以下几个部分：

（可选）一个符号字符（'+' 或 '-'）
下述格式之一：
至少一位数字，后面跟着一个点 '.'
至少一位数字，后面跟着一个点 '.' ，后面再跟着至少一位数字
一个点 '.' ，后面跟着至少一位数字
整数（按顺序）可以分成以下几个部分：

（可选）一个符号字符（'+' 或 '-'）
至少一位数字
部分数值列举如下：
["+100", "5e2", "-123", "3.1416", "-1E-16", "0123"]

部分非数值列举如下：
["12e", "1a3.14", "1.2.3", "+-5", "12e+5.4"]


示例 1：
输入：s = "0"
输出：true

示例 2：
输入：s = "e"
输出：false

示例 3：
输入：s = "."
输出：false

示例 4：
输入：s = "    .1  "
输出：true
*/

// 20：表示数值的字符串
func isNumber(s string) bool {
	s = strings.Trim(s, " ")
	if len(s) > 0 && (s[0] == '+' || s[0] == '-') {
		s = s[1:]
	}

	if len(s) == 0 {
		return false
	}

	var numflag, pointflag, expflag bool
	for i := 0; i < len(s); i++ {
		if !((s[i] >= '0' && s[i] <= '9') || s[i] == '.' || s[i] == 'e' || s[i] == 'E') {
			return false
		}

		if s[i] >= '0' && s[i] <= '9' {
			numflag = true
			continue
		}

		if s[i] == 'e' || s[i] == 'E' {
			if !numflag {
				return false
			}
			if !expflag {
				expflag, pointflag = true, true
				if i+1 == len(s) {
					return false
				}
				if s[i+1] == '+' || s[i+1] == '-' {
					i++
				}
				if i+1 >= len(s) {
					return false
				}
				continue
			} else {
				return false
			}
		}

		if s[i] == '.' {
			if expflag == true {
				return false
			}
			if pointflag == false {
				pointflag = true
				continue
			} else {
				return false
			}
		}
	}

	if !numflag && pointflag {
		return false
	}

	return numflag
}
